﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using Avalonia.Threading;
using AvaloniaApplicationDemo.DTO;
using AvaloniaApplicationDemo.IServices;
using AvaloniaApplicationDemo.Models;
using AvaloniaApplicationDemo.Services;
using AvaloniaApplicationDemo.Util;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LiveChartsCore;
using LiveChartsCore.Kernel;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;


namespace AvaloniaApplicationDemo.ViewModels;

public partial class AutoTestPageViewModel : ObservableObject
{
    [ObservableProperty] private IModbusManager _modbusManager;

    // 新增DTO属性用于UI绑定
    [ObservableProperty] private SlaveInfoDto _slaveInfoDto;

    // 业务逻辑使用的模型实例（私有，不暴露给UI）
    private SlaveInfo _slaveInfoModel;

    // private  DeviceModel _deviceModel;
    [ObservableProperty] private DeviceModel _deviceModel;
    [ObservableProperty] private ModbusDeviceData _dataPoints = new();
    [ObservableProperty] private ObservableCollection<ModbusReportModel> _modbusReportModels = new();


    // 可观测数据集合（绑定到视图，自动通知UI）
    [ObservableProperty] private ObservableCollection<VoltageCurrentDataPoint> _voltageCurrentData = new();
    [ObservableProperty] private ObservableCollection<string> _logMessages = new();

    // private readonly Timer _dataTimer;

    [ObservableProperty] private ObservableCollection<ISeries> _series = new();

    [ObservableProperty] private ObservableCollection<Axis> _xAxes = new();

    [ObservableProperty] private ObservableCollection<Axis> _yAxes = new();

    [ObservableProperty] private string _chartTitle = "实时功率监控";

    [ObservableProperty] private ushort _outputVoltage;
    [ObservableProperty] private ushort _outputCurrent;

    [ObservableProperty] private double _displayOutputVoltage;
    [ObservableProperty] private double _displayOutputCurrent;
    [ObservableProperty] private double _displayInputVoltage;
    [ObservableProperty] private bool _displayPowerSwitch = false;
    [ObservableProperty] private double _displayOutPower;

    /// <summary>
    /// 当前策略电压
    /// </summary>
    [ObservableProperty] private double _displayCurrentVoltage;

    /// <summary>
    /// 当前策略电流
    /// </summary>
    [ObservableProperty] private double _displayCurrent;


    // 定义一个委托，用于添加reports
    public Action<ModbusDeviceData, string> ReportGeneratorAction;

    // 定义一个变量，用于判断是否生成了report
    private bool _reportGenerated = false;

    /// <summary>
    /// 定义一个变量，用于判断STOP按钮是否生成了report，默认值为true
    /// </summary>
    private bool _reportGeneredStop = false;


    private ushort OutVoltageAddr = 0;
    private ushort OutCurrentAddr = 1;
    private ushort OnOFfAddr = 18;
    private ushort OnValue = 1;

    private ushort OffValue = 0;


    public AutoTestPageViewModel(DeviceModel deviceModel, SlaveInfo slaveInfo)
    {
        // 初始化设备从站信息
        DeviceModel = deviceModel;
        DeviceModel.DeviceName = "设备1";
        SlaveInfoDto =
            SlaveInfoDto.FromSlaveInfo(slaveInfo); // 将SlaveInfo转换为SlaveInfoDto 这个FormSlaveInfo方法，类似在这里实例化SlaveInfo
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo(); // 将DTO转换为模型


        // 注册委托，用于生成测试报告
        ReportGeneratorAction += GenerateTestReport;

        ModbusManager = new ModbusManager(deviceModel, _slaveInfoModel);
        ModbusManager.StatusChanged += OnModbusStatusChanged; //订阅状态改变事件StatusChanged
        InitializeChart();


        // 设置定时器模拟实时数据
        DeviceModel.DataTimer = new Timer(SlaveInfoDto.IntervalTime); // 2秒更新一次
        DeviceModel.DataTimer.Elapsed += OnDataTimerElapsed;
        DeviceModel.DataTimer.Start();
    }

    /// <summary>
    /// 生成测试报告的方法
    /// </summary>
    /// <param name="data">设备数据</param>
    /// <param name="reportType"></param>
    private void GenerateTestReport(ModbusDeviceData data, string reportType)
    {
        // 拼接测试时间
        var testTime = $"{data.OutputHours:D2}:{data.OutputMinutes:D2}:{data.OutputSeconds:D2}";

        var modbusReportModel = new ModbusReportModel
        {
            RePortTime = data.Timestamp,
            DeviceName = DeviceModel.DeviceName ?? "未知设备",
            OutputAH = data.OutputAH,
            OutputWh = data.OutputWH,
            OutputTime = testTime,
            ReportType = reportType
        };

        try
        {
            // 添加测试报告到数据库
            DataBaseManager.ModbusReportRepository.Add(modbusReportModel);
        }
        catch (Exception e)
        {
            LogMessages.Add("数据配置失败：" + e.Message);
        }


        ModbusReportModels.Add(modbusReportModel);
    }

    private void OnModbusStatusChanged(object? sender, ModbusStatusEventsAgrs e)
    {
        Dispatcher.UIThread.Post(() =>
        {
            if (!(e.Message ?? "默认消息").Contains("TimerData"))
            {
                // 处理日志
                var logMessage = e.Exception != null
                    ? $"[{DateTime.Now:HH:mm:ss}] 错误：{e.Message} - {e.Exception.Message}"
                    : $"[{DateTime.Now:HH:mm:ss}] {e.Message}";
                AddLogMessage(logMessage);
            }


            // 处理新数据
            if (e.DeviceData?.IsValid == true) UpdateDeviceData(e.DeviceData);
        });
    }

    private void UpdateDeviceData(ModbusDeviceData data)
    {
        DataPoints = data;
        DisplayOutputVoltage = data.OutputVoltage;
        DisplayOutputCurrent = data.OutputCurrent;
        DisplayInputVoltage = data.InputVoltage;
        DisplayPowerSwitch = data.OutputSwitchStatus == 1;
        DisplayOutPower = (double)data.OutputPower / 10;

        DisplayCurrentVoltage = data.VoltageSetting;
        DisplayCurrent = data.CurrentSetting;


        // 检查折线图数据源的最大电流数据是否大于20(DisplayPowerSwitch && data.OutputCurrent < 20 && VoltageCurrentData.Max(x => x.Current) > 20)
        if (VoltageCurrentData.Count > 0)
            if (DisplayPowerSwitch && data.OutputCurrent < 20)

                if (!_reportGenerated && VoltageCurrentData.Max(x => x.Current) > 20)
                {
                    ReportGeneratorAction(data, "Auto");
                    _reportGenerated = true;
                }

        if (_reportGeneredStop)
        {
            ReportGeneratorAction(data, "Stop");
            _reportGeneredStop = false;
        }

        // 添加到图表
        var dataPoint = new VoltageCurrentDataPoint(
            data.Timestamp, data.OutputVoltage, data.OutputCurrent, data.InputVoltage);
        VoltageCurrentData.Add(dataPoint);

        // 清理旧数据
        var cutoffTime = DateTime.Now.AddMinutes(-10);
        while (VoltageCurrentData.Count > 0 && VoltageCurrentData[0].Time < cutoffTime)
            VoltageCurrentData.RemoveAt(0);

        UpdateAxisLimits();
    }

    private void InitializeChart()
    {
        // 初始化X轴（时间轴）
        XAxes.Add(new Axis
        {
            Name = "时间",
            Labeler = value => new DateTime((long)value).ToString("HH:mm:ss"),
            UnitWidth = TimeSpan.FromSeconds(1).Ticks,
            MinLimit = DateTime.Now.AddMinutes(-10).Ticks,
            MaxLimit = DateTime.Now.Ticks,
            LabelsPaint = new SolidColorPaint(SKColors.Blue),
            NamePaint = new SolidColorPaint(SKColors.DarkBlue),
            TextSize = 12
        });

        // 初始化Y轴
        YAxes.Add(new Axis
        {
            Name = "电压(V)/电流(A)",
            Labeler = value => value.ToString("F2"),
            LabelsPaint = new SolidColorPaint(SKColors.Black),
            NamePaint = new SolidColorPaint(SKColors.DarkSlateGray),
            TextSize = 12
        });

        // 初始化电压系列
        Series.Add(new LineSeries<VoltageCurrentDataPoint>
        {
            Name = "输出电压(mV)",
            Values = VoltageCurrentData,
            Mapping = (dataPoint, _) => new Coordinate(dataPoint.Time.Ticks, dataPoint.Voltage),
            GeometrySize = 0,
            LineSmoothness = 0,
            Stroke = new SolidColorPaint(SKColors.Red, 3),
            Fill = null
        });
        // 初始化电流系列
        Series.Add(new LineSeries<VoltageCurrentDataPoint>
        {
            Name = "输出电流(mA)",
            Values = VoltageCurrentData,
            Mapping = (dataPoint, _) => new Coordinate(dataPoint.Time.Ticks, dataPoint.Current),
            GeometrySize = 0,
            LineSmoothness = 0,
            Stroke = new SolidColorPaint(SKColors.Blue, 3),
            Fill = null
        });
        // 初始化输入电压系列（新增）
        Series.Add(new LineSeries<VoltageCurrentDataPoint>
        {
            Name = "输入电压(mV)",
            Values = VoltageCurrentData,
            Mapping = (dataPoint, _) => new Coordinate(dataPoint.Time.Ticks, dataPoint.InputVoltage),
            GeometrySize = 0,
            LineSmoothness = 0,
            Stroke = new SolidColorPaint(SKColors.Yellow, 3), // 黄色线条
            Fill = null
        });
    }

    /// <summary>
    /// 定时器触发时，更新数据
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnDataTimerElapsed(object? sender, ElapsedEventArgs e)
    {
        if (DeviceModel.IsConnected)
            // 仅触发读取，结果通过事件返回
            _ = ModbusManager.ReadDataPointAsync(_slaveInfoModel, DeviceModel);
    }

    private void UpdateAxisLimits()
    {
        if (VoltageCurrentData.Count == 0) return;

        // 动态调整X轴范围，基于实际数据时间范围
        var firstTime = VoltageCurrentData.First().Time.Ticks;
        var lastTime = VoltageCurrentData.Last().Time.Ticks;

        // 确保至少显示一定时间范围
        var minRange = TimeSpan.FromMinutes(10).Ticks;
        if (lastTime - firstTime < minRange)
            XAxes[0].MinLimit = lastTime - minRange;
        else
            XAxes[0].MinLimit = firstTime;

        XAxes[0].MaxLimit = lastTime;
    }

    // 清除数据的命令
    [RelayCommand]
    public void ClearData()
    {
        Dispatcher.UIThread.Post(() => { VoltageCurrentData.Clear(); });
    }

    [RelayCommand]
    public async Task DisConnectCommand()
    {
        // 断开连接前置处理   
        if (!DeviceModel.IsConnected)
        {
            AddLogMessage("设备未连接");
            return;
        }

        if (DisplayPowerSwitch)
        {
            AddLogMessage("请先关闭输出电源");
            return;
        }

        var result = await ModbusManager.DisconnectAsync(DeviceModel);
        if (result)
        {
            AddLogMessage("连接已断开");
            AddLogMessage("测试停止");
            VoltageCurrentData.Clear();
        }
        else
        {
            AddLogMessage("断开连接失败");
        }
    }

    // 连接的命令
    [RelayCommand]
    public async Task ConnectCommand()
    {
        //连接前置处理
        if (DeviceModel.IsConnected)
        {
            AddLogMessage("设备已连接！请先断开连接");
            return;
        }

        // 验证DTO配置
        if (!SlaveInfoDto.Validate(out var errorMessage))
        {
            AddLogMessage(errorMessage);
            return;
        }

        //将SlaveInfoDTO转换为SlaveInfo模型
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo();
        await ModbusManager.ConnectAsync(_slaveInfoModel, DeviceModel);

        // 如果定时器已存在且间隔时间有变化，则重新设置
        if (DeviceModel.DataTimer != null && SlaveInfoDto.IntervalTime > 0)
            if (Math.Abs(DeviceModel.DataTimer.Interval - SlaveInfoDto.IntervalTime) > 0.1)
            {
                DeviceModel.DataTimer.Stop();
                DeviceModel.DataTimer.Interval = SlaveInfoDto.IntervalTime;
                DeviceModel.DataTimer.Start();
            }
    }

    [RelayCommand]
    public void SetOutputVoltageCommand()
    {
        //设置输出电压前置处理
        if (!DeviceModel.IsConnected)
        {
            AddLogMessage("设备未连接！请先连接设备");
            return;
        }

        if (OutputVoltage < 500 || OutputVoltage > DisplayInputVoltage)
        {
            AddLogMessage($"输出电压范围5-{DisplayInputVoltage}");
            return;
        }

        //将SlaveInfoDTO转换为SlaveInfo模型
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo();
        ModbusManager.SaveSettingsDataAsync(_slaveInfoModel, DeviceModel, OutVoltageAddr, OutputVoltage);
    }

    [RelayCommand]
    public void SetOutputCurrentCommand()
    {
        //设置输出电流前置处理
        if (!DeviceModel.IsConnected)
        {
            AddLogMessage("设备未连接！请先连接设备");
            return;
        }

        if (OutputCurrent <= 0 || OutputCurrent > 20000)
        {
            AddLogMessage($"输出电流范围0-20000");
            return;
        }

        //将SlaveInfoDTO转换为SlaveInfo模型
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo();
        ModbusManager.SaveSettingsDataAsync(_slaveInfoModel, DeviceModel, OutCurrentAddr, OutputCurrent);
    }

    [RelayCommand]
    public void StartTestCommand()
    {
        //开始测试前置处理
        if (!DeviceModel.IsConnected)
        {
            AddLogMessage("设备未连接！请先连接设备");
            return;
        }

        //判断是否处于开启状态
        if (DisplayPowerSwitch)
        {
            AddLogMessage("设备已开启！请先关闭设备");
            return;
        }

        if (OutputVoltage == 0 || OutputCurrent == 0)
        {
            AddLogMessage("请设置输出电压和电流");
            return;
        }

        //启动测试时，重置stop的测试报告生成状态为false
        _reportGeneredStop = false;
        _reportGenerated = false;


        //将SlaveInfoDTO转换为SlaveInfo模型
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo();

        ModbusManager.SaveSettingsDataAsync(_slaveInfoModel, DeviceModel, OnOFfAddr, OnValue);
    }

    [RelayCommand]
    public async Task StopTestCommand()
    {
        //停止测试前置处理
        if (!DeviceModel.IsConnected)
        {
            AddLogMessage("设备未连接！请先连接设备");
            return;
        }

        _reportGeneredStop = true;
        // _reportGenerated = false;
        // 先读取设备数据用于生成报告
        await ModbusManager.ReadDataPointAsync(_slaveInfoModel, DeviceModel);


        //将SlaveInfoDTO转换为SlaveInfo模型
        _slaveInfoModel = SlaveInfoDto.ToSlaveInfo();
        ModbusManager.SaveSettingsDataAsync(_slaveInfoModel, DeviceModel, OnOFfAddr, OffValue);
    }


    [RelayCommand]
    public void ClearLogCommand()
    {
        LogMessages.Clear();
    }

// 添加日志的方法
    public void AddLogMessage(string message)
    {
        Dispatcher.UIThread.Post(() =>
        {
            LogMessages.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}");

            // 限制日志数量，避免内存溢出
            if (LogMessages.Count > 1000) LogMessages.RemoveAt(0);
        });
    }
}

/// <summary>
/// Charts数据点类
/// </summary>
public class VoltageCurrentDataPoint
{
    public DateTime Time { get; set; }
    public double Voltage { get; set; }
    public double Current { get; set; }
    public double InputVoltage { get; set; } // 添加输入电压属性

    public VoltageCurrentDataPoint(DateTime time, double voltage, double current, double inputVoltage)
    {
        Time = time;
        Voltage = voltage;
        Current = current;
        InputVoltage = inputVoltage;
    }
}